package com.example.ecommerce.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.ecommerce.common.exception.BusinessException;
import com.example.ecommerce.dto.ProductCategoryDTO;
import com.example.ecommerce.entity.Product;
import com.example.ecommerce.entity.ProductCategory;
import com.example.ecommerce.mapper.ProductCategoryMapper;
import com.example.ecommerce.service.ProductCategoryService;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory>
        implements ProductCategoryService {

    @Autowired
    private ProductCategoryMapper categoryMapper;
    
    @Autowired
    private ModelMapper modelMapper;

    @Override
    public ProductCategoryDTO getCategoryById(Long id) {
        ProductCategory category = categoryMapper.selectById(id);
        if (category == null) {
            throw new BusinessException("分类不存在");
        }
        return modelMapper.map(category, ProductCategoryDTO.class);
    }

    @Override
    public List<ProductCategoryDTO> getCategoryTree() {
        // 获取所有分类
        List<ProductCategory> allCategories = categoryMapper.selectList(
            new LambdaQueryWrapper<ProductCategory>()
                .eq(ProductCategory::getStatus, 1)
                .orderByAsc(ProductCategory::getSort)
        );
        
        // 转换为DTO
        List<ProductCategoryDTO> categoryDTOs = allCategories.stream()
                .map(category -> modelMapper.map(category, ProductCategoryDTO.class))
                .collect(Collectors.toList());
        
        // 构建树形结构
        return buildCategoryTree(categoryDTOs, null);
    }


    @Override
    public ProductCategoryDTO createCategory(ProductCategoryDTO categoryDTO) {
        // 验证父分类
        if (categoryDTO.getParentId() != null && categoryDTO.getParentId() != 0) {
            ProductCategory parentCategory = categoryMapper.selectById(categoryDTO.getParentId());
            if (parentCategory == null) {
                throw new BusinessException("父分类不存在");
            }
            // 设置层级
            categoryDTO.setLevel(parentCategory.getLevel() + 1);
        } else {
            categoryDTO.setParentId(0L);
            categoryDTO.setLevel(1);
        }
        
        // 检查同级分类名称是否重复
        if (checkNameExists(categoryDTO.getName(), categoryDTO.getParentId(), null)) {
            throw new BusinessException("同级分类名称已存在");
        }
        
        // 转换并保存
        ProductCategory category = modelMapper.map(categoryDTO, ProductCategory.class);
        category.setCreatedAt(LocalDateTime.now());
        categoryMapper.insert(category);
        
        return modelMapper.map(category, ProductCategoryDTO.class);
    }

    @Override
    public ProductCategoryDTO updateCategory(Long id, ProductCategoryDTO categoryDTO) {
        ProductCategory existingCategory = categoryMapper.selectById(id);
        if (existingCategory == null) {
            throw new BusinessException("分类不存在");
        }
        
        // 检查是否修改了父分类
        if (!Objects.equals(existingCategory.getParentId(), categoryDTO.getParentId())) {
            // 验证新的父分类
            if (categoryDTO.getParentId() != null && categoryDTO.getParentId() != 0) {
                ProductCategory parentCategory = categoryMapper.selectById(categoryDTO.getParentId());
                if (parentCategory == null) {
                    throw new BusinessException("父分类不存在");
                }
                // 检查是否将分类设置为自己的子分类
                if (isChildCategory(id, categoryDTO.getParentId())) {
                    throw new BusinessException("不能将分类设置为自己的子分类");
                }
                categoryDTO.setLevel(parentCategory.getLevel() + 1);
            } else {
                categoryDTO.setParentId(0L);
                categoryDTO.setLevel(1);
            }
        }
        
        // 检查同级分类名称是否重复
        if (!existingCategory.getName().equals(categoryDTO.getName()) &&
                checkNameExists(categoryDTO.getName(), categoryDTO.getParentId(), id)) {
            throw new BusinessException("同级分类名称已存在");
        }
        
        // 更新分类
        ProductCategory category = modelMapper.map(categoryDTO, ProductCategory.class);
        category.setId(id);
        categoryMapper.updateById(category);
        
        return modelMapper.map(category, ProductCategoryDTO.class);
    }

    @Override
    public void deleteCategory(Long id) {
        // 检查是否存在子分类
        List<ProductCategory> children = categoryMapper.selectList(
            new LambdaQueryWrapper<ProductCategory>()
                .eq(ProductCategory::getParentId, id)
        );
        if (!children.isEmpty()) {
            throw new BusinessException("存在子分类，无法删除");
        }
        
        // 检查是否有关联的商品
        Long productCount = categoryMapper.countProducts(id);
        if (productCount > 0) {
            throw new BusinessException("分类下存在商品，无法删除");
        }
        
        categoryMapper.deleteById(id);
    }

    @Override
    public boolean exists(Long id) {
        return categoryMapper.selectById(id) != null;
    }

    @Override
    public List<ProductCategoryDTO> getAllEnabledCategories() {
        // 查询所有启用的分类
        List<ProductCategory> categories = list(new LambdaQueryWrapper<ProductCategory>()
                .eq(ProductCategory::getStatus, 1)
                .orderByAsc(ProductCategory::getSort));
        
        // 转换为DTO
        List<ProductCategoryDTO> categoryDTOs = categories.stream()
                .map(category -> {
                    ProductCategoryDTO dto = modelMapper.map(category, ProductCategoryDTO.class);
                    // 设置是否有子分类
                    dto.setHasChildren(hasChildren(category.getId()));
                    // 设置商品数量
                    dto.setProductCount(categoryMapper.countProducts(category.getId()));
                    return dto;
                })
                .collect(Collectors.toList());
        
        // 构建树形结构
        return buildCategoryTree(categoryDTOs, 0L);
    }

    /**
     * 构建分类树
     */
    private List<ProductCategoryDTO> buildCategoryTree(List<ProductCategoryDTO> categories, Long parentId) {
        return categories.stream()
                .filter(category -> Objects.equals(category.getParentId(), parentId))
                .peek(category -> {
                    // 递归设置子分类
                    List<ProductCategoryDTO> children = buildCategoryTree(categories, category.getId());
                    category.setChildren(children);
                    // 更新是否有子分类的标志
                    category.setHasChildren(!children.isEmpty());
                })
                .collect(Collectors.toList());
    }

    /**
     * 检查是否有子分类
     */
    private boolean hasChildren(Long categoryId) {
        return count(new LambdaQueryWrapper<ProductCategory>()
                .eq(ProductCategory::getParentId, categoryId)
                .eq(ProductCategory::getStatus, 1)) > 0;
    }

    private boolean checkNameExists(String name, Long parentId, Long excludeId) {
        LambdaQueryWrapper<ProductCategory> queryWrapper = new LambdaQueryWrapper<ProductCategory>()
                .eq(ProductCategory::getName, name)
                .eq(ProductCategory::getParentId, parentId);
        
        if (excludeId != null) {
            queryWrapper.ne(ProductCategory::getId, excludeId);
        }
        
        return categoryMapper.selectCount(queryWrapper) > 0;
    }

    private boolean isChildCategory(Long categoryId, Long parentId) {
        while (parentId != null && parentId != 0) {
            ProductCategory parent = categoryMapper.selectById(parentId);
            if (parent == null) {
                return false;
            }
            if (parent.getId().equals(categoryId)) {
                return true;
            }
            parentId = parent.getParentId();
        }
        return false;
    }
} 